#include <iostream>
#include <string>
#include <vector>
#include <chrono>
#include <sw/redis++/redis++.h>
#include "../util.hpp"

using namespace std::chrono_literals;
using sw::redis::Redis;

void test1(sw::redis::Redis &redis){
    std::cout << "Set 带有超时时间" << std::endl;
    redis.flushall();

    redis.set("key", "111", 10s);
 
    std::this_thread::sleep_for(3s);
 
    long long time = redis.ttl("key");
    std::cout << "time: " << time << std::endl;
}

void test2(sw::redis::Redis &redis){
    std::cout << "set NX 和 XX" << std::endl;
    redis.flushall();
 
    redis.set("key", "111");
 // set 的重载版本中, 没有单独提供 NX 和 XX 的版本, 必须搭配过期时间的版本来使用. 
    redis.set("key", "222", 0s, sw::redis::UpdateType::EXIST);
 
    auto value = redis.get("key");
    if (value) {
        std::cout << "value: " << value.value() << std::endl;
    } else {
        std::cout << "key 不存在!" << std::endl;
    }
}

void test3(sw::redis::Redis &redis){
    std::cout << "mset & mget" << std::endl;
    redis.flushall();

    // // 写法一: 初始化列表描述多个键值对
    // redis.mset({
    //     std::make_pair("key1", "value1"),
    //     std::make_pair("key2", "value2"),
    //     std::make_pair("key3", "value3")
    // });
    // 写法二: 使用 std::vector<std::pair<std::string, std::string>> 描述多个键值对, 然后以迭代器的形式告诉 mset
    std::vector<std::pair<std::string, std::string>> keys = {
        {"key1", "111"},
        {"key2", "222"},
        {"key3", "333"}
    };
    redis.mset(keys.begin(), keys.end());
    
    std::vector<sw::redis::OptionalString> res;
    auto it = std::back_inserter(res);
    redis.mget({"key1", "key2", "key3"}, it);
    printContainerOptional(res);
}

void test4(Redis& redis) {
    std::cout << "getrange 和 setrange" << std::endl;
    redis.flushall();

    redis.set("key", "abcdefghijk"); 
    std::string result = redis.getrange("key", 2, 5);
    std::cout << "result: " << result << std::endl;
 
    redis.setrange("key", 2, "xyz");
 
    auto value = redis.get("key");
    std::cout << "value: " << value.value() << std::endl;
}

void test5(Redis& redis) {
    std::cout << "incr 和 decr" << std::endl;
    redis.flushall();
 
    redis.set("key", "100");
    //对比关注 如下两种返回结果
    
    //返回结果1：long long
    long long result = redis.incr("key");
    std::cout << "result: " << result << std::endl;
 
    //返回结果2:对象
    auto value = redis.get("key");
    std::cout << "value: " << value.value() << std::endl;
 
    result = redis.decr("key");
    std::cout << "result: " << result << std::endl;
 
    value = redis.get("key");
    std::cout << "value: " << value.value() << std::endl;
}


int main(){
    sw::redis::Redis redis("tcp://127.0.0.1:6379");
    // 如果 Redis 设置了密码，请在这里添加认证
    redis.auth("123456");  // 替换为你的 Redis 密码
    test5(redis);

    return 0;
}